package cn.oi.klittle.era.widget.progress

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import cn.oi.klittle.era.entity.widget.progressbar.KCircleProgressBarEntry
import cn.oi.klittle.era.widget.compat.K6BubblesWidget
import cn.oi.klittle.era.widget.compat.KTextView

//                fixme 环形圆形进度条使用案例：
//                kCircleProgressBar {
//                    //backgroundColor(Color.WHITE)
//                    var circleProgress = 85f//fixme 当前进度。
//                    circleProgressBar {
//                        //背景环形
//                        bg_ring_color = Color.BLUE//环形颜色
//                        bg_ring_width = kpx.x(40f)//环形宽度
//                        progress = circleProgress//进度值（0~100f）
//                        //bgLeftMargin = kpx.x(10f)//环形背景左外补丁。
//                        //bgTopMargin = kpx.x(10f)
//                        //bgRightMargin = kpx.x(10f)
//                        //bgBottomMargin = kpx.x(10f)
//                        bgHorizontalColors(Color.TRANSPARENT, Color.WHITE)//背景水平颜色渐变
//                        //bgSweepGradientColors(Color.TRANSPARENT, Color.WHITE, Color.WHITE,Color.TRANSPARENT)//背景环形扫描渐变（最右边开始，顺时针渐变。）开始和结尾颜色最好一致。(比较好看)
//                        //进度条环形
//                        progress_ring_color = Color.RED
//                        progress_ring_width = kpx.x(30f)//（两个环形的中心是一致的。）
//                        progressVerticalColors(Color.WHITE, Color.parseColor("#00A4FF"))//环形进度条颜色垂直渐变(优先级比水平高)
//                        //progressHorizontalColors(Color.RED, Color.WHITE,Color.TRANSPARENT)//环形进度条水平颜色渐变
//                        //progressSweepGradientColors(Color.RED, Color.BLUE,Color.GREEN,Color.YELLOW,Color.WHITE,Color.RED)//fixme 环形扫描渐变（最右边开始，顺时针渐变。），优先级最高。开始和结尾颜色最好一致。
//                        progressLeftMargin = 0f//环形进度条左外补丁。
//                        progressTopMargin = 0f
//                        progressRightMargin = 0f
//                        progressBottomMargin = 0f
//                    }
//                    gravity = Gravity.CENTER
//                    textColor = Color.WHITE
//                    textSize = kpx.textSizeX(150)
//                    isBold(true)
//                    text = circleProgress.toString() + "%"
//                    //fixme 开始动画效果
//                    starCircleProgressAnime(duration = 1500) {
//                        var str: String? = (it * circleProgress).toString()
//                        str = KStringUtils.decimalString(str, 0)
//                        str?.let {
//                            if (it.length > 2) {
//                                str = str?.substring(0, 2)//保留两位数
//                            }
//                        }
//                        setText(str + "%")//显示当前进度。
//                    }
//                }.lparams {
//                    width = kpx.x(500)
//                    height = kpx.x(500)
//                    topMargin = kpx.x(20)
//                }

/**
 * 圆形（环形）进度条;
 */
open class KCircleProgressBar : KTextView {

    constructor(viewGroup: ViewGroup) : super(viewGroup.context) {
        viewGroup.addView(this)//直接添加进去,省去addView(view)
    }

    constructor(viewGroup: ViewGroup, HARDWARE: Boolean) : super(viewGroup.context) {
        if (HARDWARE) {
            setLayerType(View.LAYER_TYPE_HARDWARE, null)
        } else {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null)
        }
        viewGroup.addView(this)//直接添加进去,省去addView(view)
    }

    constructor(context: Context) : super(context) {}

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}

    //按下
    var circleProgressBar_press: KCircleProgressBarEntry? = null

    fun circleProgressBar_press(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        if (circleProgressBar_press == null) {
            circleProgressBar_press = getMCircleProgressBar().copy()//整个属性全部复制过来。
        }
        block(circleProgressBar_press!!)
        invalidate()
        return this
    }

    //鼠标悬浮
    var circleProgressBar_hover: KCircleProgressBarEntry? = null

    fun circleProgressBar_hover(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        if (circleProgressBar_hover == null) {
            circleProgressBar_hover = getMCircleProgressBar().copy()//整个属性全部复制过来。
        }
        block(circleProgressBar_hover!!)
        invalidate()
        return this
    }

    //聚焦
    var circleProgressBar_focuse: KCircleProgressBarEntry? = null

    fun circleProgressBar_focuse(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        if (circleProgressBar_focuse == null) {
            circleProgressBar_focuse = getMCircleProgressBar().copy()//整个属性全部复制过来。
        }
        block(circleProgressBar_focuse!!)
        invalidate()
        return this
    }

    //选中
    var circleProgressBar_selected: KCircleProgressBarEntry? = null

    fun circleProgressBar_selected(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        if (circleProgressBar_selected == null) {
            circleProgressBar_selected = getMCircleProgressBar().copy()//整个属性全部复制过来。
        }
        block(circleProgressBar_selected!!)
        invalidate()
        return this
    }

    //不可用
    var circleProgressBar_notEnable: KCircleProgressBarEntry? = null

    fun circleProgressBar_notEnable(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        if (circleProgressBar_notEnable == null) {
            circleProgressBar_notEnable = getMCircleProgressBar().copy()//整个属性全部复制过来。
        }
        block(circleProgressBar_notEnable!!)
        invalidate()
        return this
    }

    //fixme 正常状态（先写正常样式，再写其他状态的样式，因为其他状态的样式初始值是复制正常状态的样式的。）
    var circleProgressBar: KCircleProgressBarEntry? = null

    private fun getMCircleProgressBar(): KCircleProgressBarEntry {
        if (circleProgressBar == null) {
            circleProgressBar = KCircleProgressBarEntry()
        }
        return circleProgressBar!!
    }

    fun circleProgressBar(block: KCircleProgressBarEntry.() -> Unit): K6BubblesWidget {
        block(getMCircleProgressBar())
        invalidate()
        return this
    }

    //fixme 气泡样式，最后绘制。最后显示。即在切割圆角radius{}的上面。
    override fun draw2Last2(canvas: Canvas, paint: Paint) {
        super.draw2Last2(canvas, paint)
        drawCircleProgressBar(canvas, paint, this)
    }

    private var circleProgressBarModel: KCircleProgressBarEntry? = null
    private fun drawCircleProgressBar(canvas: Canvas, paint: Paint, view: View) {
        view?.apply {
            if (circleProgressBar != null) {
                if (width <= 0 || height <= 0) {
                    return
                }
                circleProgressBarModel = null
                if (isPressed && circleProgressBar_press != null) {
                    //按下
                    circleProgressBarModel = circleProgressBar_press
                } else if (isHovered && circleProgressBar_hover != null) {
                    //鼠标悬浮
                    circleProgressBarModel = circleProgressBar_hover
                } else if (isFocused && circleProgressBar_focuse != null) {
                    //聚焦
                    circleProgressBarModel = circleProgressBar_focuse
                } else if (isSelected && circleProgressBar_selected != null) {
                    //选中
                    circleProgressBarModel = circleProgressBar_selected
                }
                if (isEnabled == false && circleProgressBar_notEnable != null) {
                    //不可用
                    circleProgressBarModel = circleProgressBar_notEnable
                }
                //正常
                if (circleProgressBarModel == null) {
                    circleProgressBarModel = circleProgressBar
                }
                circleProgressBarModel?.let {
                    if (it.isDraw) {
                        paint.setShader(null)
                        drawCircleProgressBar(canvas, paint, it)
                        paint.setShader(null)//防止其他地方受影响，所以渲染清空。
                    }
                }
            }
        }
    }

    var circleProgressBarFloat = 1f//fixme 用于实现动画效果。

    /**
     * fixme 开始环形进度动画效果
     * @param duration 动画时间
     * @param callback 返回当前属性动画的值。
     */
    fun starCircleProgressAnime(duration: Long = 1000L, callback: ((progress: Float) -> Unit)? = null) {
        ofFloat("circleProgressBarFloat", 0, duration, 0F, 1F) {
            var progress = it
            callback?.let {
                it(progress)
            }
        }
    }


    //fixme 绘制圆形进度条
    private fun drawCircleProgressBar(canvas: Canvas, paint: Paint, circleProgressBar: KCircleProgressBarEntry) {
        circleProgressBar?.apply {
            if (!isDraw) {
                return
            }
            paint.isAntiAlias = true
            paint.isDither = true
            paint.setDither(true)//防抖动，柔和效果。
            paint.strokeCap = Paint.Cap.ROUND
            paint.strokeJoin = Paint.Join.ROUND//fixme 圆形线帽
            paint.setShader(null)
            if (bg_ring_width < 0) {
                bg_ring_width = (width / 10f)
            }
            if (progress_ring_width < 0) {
                progress_ring_width = (width / 10f)
            }
            var offset = bg_ring_width / 2//fixme 偏移量。
            if (progress_ring_width > bg_ring_width) {
                offset = progress_ring_width / 2//fixme 以环形宽度长的为准，保证背景和进度条。两个环形的中心保持一致。亲测有效。
            }
            if (isDrawBgRing && bg_ring_width != 0F && bg_ring_color != Color.TRANSPARENT) {
                //绘制环形背景
                paint.setColor(bg_ring_color)
                paint.strokeWidth = bg_ring_width.toFloat()
                paint.style = Paint.Style.STROKE
                var left = offset + bgLeftMargin
                var top = offset + bgTopMargin
                var right = width.toFloat() - offset - bgRightMargin
                var bottom = height.toFloat() - offset - bgBottomMargin
                var mRectF = RectF(left, top, right, bottom)
                var shader: LinearGradient? = null
                if (bgSweepGradientColors != null) {
                    var shader: SweepGradient? = null
                    //fixme 背景环形扫描渐变（最右边开始，顺时针渐变。）开始渐变颜色和结束渐变数最好一致。（比较好看）
                    //fixme 背景环形扫描渐变(优先级最高)
                    var centerX = left + (right - left) / 2
                    var centerY = top + (bottom - top) / 2
                    if (bgSweepGradientColors!!.size == 1) {
                        var bgHorizontalColors = IntArray(2)
                        bgHorizontalColors[0] = bgSweepGradientColors!![0]
                        bgHorizontalColors[1] = bgSweepGradientColors!![0]
                        shader = SweepGradient(centerX, centerY, bgHorizontalColors, null)
                    } else {
                        shader = SweepGradient(centerX, centerY, bgSweepGradientColors!!, null)
                    }
                    if (shader != null) {
                        paint.setShader(shader)
                    }
                } else if (bgVerticalColors != null) {
                    //fixme 垂直渐变(优先级比水平高)
                    if (bgVerticalColors!!.size == 1) {
                        var bgHorizontalColors = IntArray(2)
                        bgHorizontalColors[0] = bgVerticalColors!![0]
                        bgHorizontalColors[1] = bgVerticalColors!![0]
                        shader = LinearGradient(0f, top, 0f, bottom, bgHorizontalColors, null, Shader.TileMode.MIRROR)
                    } else {
                        shader = LinearGradient(0f, top, 0f, bottom, bgVerticalColors!!, null, Shader.TileMode.MIRROR)
                    }
                } else if (bgHorizontalColors != null) {
                    //fixme 水平渐变
                    if (bgHorizontalColors!!.size == 1) {
                        var bgHorizontalColors2 = IntArray(2)
                        bgHorizontalColors2[0] = bgHorizontalColors!![0]
                        bgHorizontalColors2[1] = bgHorizontalColors!![0]
                        shader = LinearGradient(left, 0f, right, 0f, bgHorizontalColors2, null, Shader.TileMode.MIRROR)
                    } else {
                        shader = LinearGradient(left, 0f, right, 0f, bgHorizontalColors!!, null, Shader.TileMode.MIRROR)
                    }
                }
                if (shader != null) {
                    paint.setShader(shader)
                }
                canvas.drawArc(mRectF, 0f, 360f, false, paint);
                paint.setShader(null)
            }
            if (isDrawProgressRing && progress_ring_width != 0F && progress_ring_color != Color.TRANSPARENT) {
                //绘制环形背景
                paint.setColor(progress_ring_color)
                paint.strokeWidth = progress_ring_width.toFloat()
                paint.style = Paint.Style.STROKE
                var left = offset + progressLeftMargin
                var top = offset + progressTopMargin
                var right = width.toFloat() - offset - progressRightMargin
                var bottom = height.toFloat() - offset - progressBottomMargin
                var mRectF = RectF(left, top, right, bottom)
                var shader: LinearGradient? = null
                if (progressSweepGradientColors != null) {
                    var shader: SweepGradient? = null
                    //fixme 环形扫描渐变（最右边开始，顺时针渐变。）开始渐变颜色和结束渐变数最好一致。（比较好看）
                    //fixme 环形扫描渐变(优先级最高)
                    var centerX = left + (right - left) / 2
                    var centerY = top + (bottom - top) / 2
                    if (progressSweepGradientColors!!.size == 1) {
                        var bgHorizontalColors = IntArray(2)
                        bgHorizontalColors[0] = progressSweepGradientColors!![0]
                        bgHorizontalColors[1] = progressSweepGradientColors!![0]
                        shader = SweepGradient(centerX, centerY, bgHorizontalColors, null)
                    } else {
                        shader = SweepGradient(centerX, centerY, progressSweepGradientColors!!, null)
                    }
                    if (shader != null) {
                        paint.setShader(shader)
                    }
                } else if (progressVerticalColors != null) {
                    //fixme 垂直渐变(优先级比水平高)
                    if (progressVerticalColors!!.size == 1) {
                        var bgHorizontalColors = IntArray(2)
                        bgHorizontalColors[0] = progressVerticalColors!![0]
                        bgHorizontalColors[1] = progressVerticalColors!![0]
                        shader = LinearGradient(0f, top, 0f, bottom, bgHorizontalColors, null, Shader.TileMode.MIRROR)
                    } else {
                        shader = LinearGradient(0f, top, 0f, bottom, progressVerticalColors!!, null, Shader.TileMode.MIRROR)
                    }
                } else if (progressHorizontalColors != null) {
                    //fixme 水平渐变
                    if (progressHorizontalColors!!.size == 1) {
                        var bgHorizontalColors = IntArray(2)
                        bgHorizontalColors[0] = progressHorizontalColors!![0]
                        bgHorizontalColors[1] = progressHorizontalColors!![0]
                        shader = LinearGradient(left, 0f, right, 0f, bgHorizontalColors, null, Shader.TileMode.MIRROR)
                    } else {
                        shader = LinearGradient(left, 0f, right, 0f, progressHorizontalColors!!, null, Shader.TileMode.MIRROR)
                    }
                }
                if (shader != null) {
                    paint.setShader(shader)
                }
                canvas.drawArc(mRectF, startAngle, 360f * (progress / 100f) * circleProgressBarFloat, false, paint);
                paint.setShader(null)
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        circleProgressBar = null
        circleProgressBar_focuse = null
        circleProgressBar_hover = null
        circleProgressBar_press = null
        circleProgressBar_selected = null
        circleProgressBar_notEnable = null
        circleProgressBarModel = null
    }

}